/**
 * @description users service
 */

const _ = require('lodash')
const UserModel = require('../model/user')
const { DEFAULT_PAGE_SIZE } = require('../config/constant')

const defaultPageCondition = {
  pageIndex: 0,
  pageSize: DEFAULT_PAGE_SIZE
}

/**
 * 查询用户列表
 * @param {object} whereOpt 查询条件
 * @param {object} pageOpt 分页数据
 */
async function findUserList(whereOpt = {}, pageOpt = {}) {
  const pageCondition = { ...defaultPageCondition, ...pageOpt }
  const { pageSize, pageIndex } = pageCondition
  const skip = pageIndex * pageSize

  const result = await UserModel.find(whereOpt)
    .skip(skip) // 跳过多少条
    .limit(pageSize) // 每页多少条
    .sort({ id: -1 }) // 倒序
  // .lean() // 直接返回 object 对象，不需要返回 Document 类型的对象，加快查询速度，但是会使getter和转化方法都失效

  const count = await UserModel.find(whereOpt).count()

  return {
    count,
    list: result,
    pageSize,
    pageIndex
  }
}

/**
 * 修改用户
 * @param {object} updateData 要修改的数据
 * @param {object} whereOpt 条件
 * @returns {Promise<boolean>} true/false
 */
async function updateUser(updateData = {}, whereOpt = {}) {
  // 保证数据不为空
  if (_.isEmpty(updateData)) return false
  if (_.isEmpty(whereOpt)) return false

  const result = await UserModel.findOneAndUpdate(whereOpt, updateData, { new: true })
  return !!result
}

/**
 * 批量更新用户数据
 * @param {object} updateData 要更新的数据
 * @param {object} whereOpt 查询提交件
 * @returns {Promise<boolean>} true/false
 */
async function updateUsers(updateData = {}, whereOpt = {}) {
  // 保证数据不为空
  if (_.isEmpty(updateData)) return false
  if (_.isEmpty(whereOpt)) return false

  // const result = await UserModel.updateMany({ id: { $in: [1, 2] } }, { $set: { isFrozen: true } })
  const result = await UserModel.updateMany(whereOpt, updateData)
  console.log('updateUsers', result)
  return result.modifiedCount !== 0
}

/**
 * 获取总数
 * @param {object} whereOpt 条件
 */
async function getUsersCount(whereOpt = {}) {
  const result = await UserModel.count(whereOpt)
  return result
}

/**
 * 按月，统计创建数量
 * @param {Date} startTime 开始时间
 * @param {Date} endTime 结束时间
 */
async function getCreatedCountMonthly(startTime, endTime) {
  const result = await UserModel.aggregate([
    { $match: { createdAt: { $gte: startTime, $lte: endTime } } },
    // 执行完 $project 管道，得到的结果格式为{ month }；format 时间格式：%Y-%m-%d %H:%M
    { $project: { month: { $dateToString: { format: '%Y-%m', date: '$createdAt', timezone: '+08:00' } } } }, // 世界标准时间和我们时差相差8，我们是+8时区，所以+8小时就是系统当前时间
    { $group: { _id: '$month', count: { $sum: 1 } } }, // 按照 $month 进行分组（一组为1个月）
    { $sort: { _id: 1 } }
  ]).exec()

  return result
}

/**
 * 按天，统计创建数量
 * @param {Date} startTime 开始时间
 * @param {Date} endTime 结束时间
 */
async function getCreatedCountDaily(startTime, endTime) {
  const result = await UserModel.aggregate([
    // 执行完 $match 管道后(match)，得到的查询结果会输入到 $project 管道
    { $match: { createdAt: { $gte: startTime, $lte: endTime } } }, // createdAt >= startTimeStr and createdAt <= endTimeStr
    // 执行完 $project 管道，得到的结果格式为{ day }, 把这个结果输入 $group 管道； format 时间格式：%Y-%m-%d %H:%M
    { $project: { day: { $dateToString: { format: '%Y-%m-%d', date: '$createdAt', timezone: '+08:00' } } } }, // 世界标准时间和我们时差相差8，我们是+8时区，所以+8小时就是系统当前时间
    // $group管道执行完毕，输出的结果输入到$sort管道
    { $group: { _id: '$day', count: { $sum: 1 } } }, // 按照 $day 进行分组（一组为1天）
    // $sort执行完毕，输出最终结果集
    { $sort: { _id: 1 } } // 得到的结果集按照 _id 升序排列；也就是按 $day 升序排序
  ]).exec()

  return result
}

module.exports = {
  findUserList,
  updateUser,
  updateUsers,
  getUsersCount,
  getCreatedCountMonthly,
  getCreatedCountDaily
}
